/* ----------------------------------------------------------------------
*
* Copyright (C) 2024 XiaoFei. All rights reserved.
*
* @file:		LingZhi_AD9959.c
* @author:		XiaoFei
* @Date:     	19-July-2024
* @Revision: 	V1
* @Project: 	XiaoFei BSP Library
*
* -------------------------------------------------------------------- */

#include "stm32f4xx.h"
#include "XiaoFei_Delay.h"
#include "LingZhi_AD9959.h"

/* 
* @function: 	LingZhi_AD9959_Reset
*/
void LingZhi_AD9959_Reset(void)
{
	AD9959_CS(1);
	AD9959_SCK(0);
	AD9959_IU(0);
	AD9959_P0(0);
	AD9959_P1(0);
	AD9959_P2(0);
	AD9959_P3(0);
	AD9959_SD0(0);
	AD9959_SD1(0);
	AD9959_SD2(0);
	AD9959_SD3(0);
	AD9959_RST(0);
	XiaoFei_Delay_us(1);
	AD9959_RST(1);
	XiaoFei_Delay_us(10);
	AD9959_RST(0);
}

/* 
* @function: 	LingZhi_AD9959_Init
*/
void LingZhi_AD9959_Init(void)
{
	AD9959_RCC_PDN(1);
	AD9959_RCC_RST(1);
	AD9959_RCC_SD0(1);
	AD9959_RCC_SD1(1);
	AD9959_RCC_SD2(1);
	AD9959_RCC_SD3(1);
	AD9959_RCC_SCK(1);
	AD9959_RCC_CS(1);
	AD9959_RCC_IU(1);
	AD9959_RCC_P0(1);
	AD9959_RCC_P1(1);
	AD9959_RCC_P2(1);
	AD9959_RCC_P3(1);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; 
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT ;		
	GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;	
	GPIO_InitStructure.GPIO_Pin=AD9959_PIN_PDN;
	GPIO_Init(AD9959_GPIO_PDN,&GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Pin=AD9959_PIN_RST;
	GPIO_Init(AD9959_GPIO_RST,&GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Pin=AD9959_PIN_SD0;
	GPIO_Init(AD9959_GPIO_SD0,&GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Pin=AD9959_PIN_SD1;
	GPIO_Init(AD9959_GPIO_SD1,&GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Pin=AD9959_PIN_SD2;
	GPIO_Init(AD9959_GPIO_SD2,&GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Pin=AD9959_PIN_SD3;
	GPIO_Init(AD9959_GPIO_SD3,&GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Pin=AD9959_PIN_SCK;
	GPIO_Init(AD9959_GPIO_SCK,&GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Pin=AD9959_PIN_CS;
	GPIO_Init(AD9959_GPIO_CS,&GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Pin=AD9959_PIN_IU;
	GPIO_Init(AD9959_GPIO_IU,&GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Pin=AD9959_PIN_P0;
	GPIO_Init(AD9959_GPIO_P0,&GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Pin=AD9959_PIN_P1;
	GPIO_Init(AD9959_GPIO_P1,&GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Pin=AD9959_PIN_P2;
	GPIO_Init(AD9959_GPIO_P2,&GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Pin=AD9959_PIN_P3;
	GPIO_Init(AD9959_GPIO_P3,&GPIO_InitStructure);
	LingZhi_AD9959_Reset();
}

/* 
* @function:    LingZhi_AD9959_WrReg
* @parameter:   [in] Reg				The AD9959 reg.
* @parameter:   [in] Num				The size of data.
* @parameter:   [in] Data				The data to be set.
* @parameter:   [in] temp				Set 0x01 while io update.
*/
static void LingZhi_AD9959_WrReg(unsigned char Reg, unsigned char Num, unsigned char *Data,unsigned char temp) 
{
	unsigned char Control=Reg;
	unsigned char Value=0;
	AD9959_SCK(0);
	AD9959_CS(0);
	for(unsigned char i=0;i<8;i++)
	{
		AD9959_SCK(0);
		AD9959_SD0(0x80==(Control&0x80));
		AD9959_SCK(1);
		Control<<=1;
	}
	AD9959_SCK(0);
	for(unsigned char j=0;j<Num;j++)
	{
		Value=Data[j];
		for(unsigned char k=0;k<8;k++)
		{
			AD9959_SCK(0);
			AD9959_SD0(0x80==(Value&0x80));
			AD9959_SCK(1);
			Value<<=1;
		}
		AD9959_SCK(0);
	}
	if(temp==1) 
	{
		AD9959_IU(0);
		XiaoFei_Delay_us(2);
		AD9959_IU(1);
		XiaoFei_Delay_us(2);
		AD9959_IU(0);
	}
}

/* 
* @function:    LingZhi_AD9959_WrFreq
* @parameter:   [in] f				    The frequency will be set.
* @parameter:   [out] Fre				The frequency num to set.
*/
static void LingZhi_AD9959_WrFreq(double f,unsigned char *Fre)
{
	long int y=(long int)(f*(4294967296.0/AD9959_SysClk));
	unsigned char z;
	z=(unsigned char)(y>>24);
	Fre[0]=z;
	z=(unsigned char)(y>>16);
	Fre[1]=z;
	z=(unsigned char)(y>>8);
	Fre[2]=z;
	z=(unsigned char)(y>>0);
	Fre[3]=z;
}

/* 
* @function:    LingZhi_AD9959_WrPhase
* @parameter:   [in] f				    The Phase will be set.
* @parameter:   [out] Pha				The Phase num to set.
*/
static void LingZhi_AD9959_WrPhase(double f,unsigned char *Pha)
{
	long int y=(long int)(f*(16384.0/360));
	unsigned char z;
	z=(unsigned char)(y>>8);
	Pha[0]=z;
	z=(unsigned char)(y>>0);
	Pha[1]=z;
}

/* 
* @function:    LingZhi_AD9959_WrAmp
* @parameter:   [in] f				    The amplitute will be set.
* @parameter:   [out] Amp				The amplitute num to set.
* @parameter:   [out] ASR				The amplitute num to set.
*/
static void LingZhi_AD9959_WrAmp(double f,unsigned char *Amp,unsigned char *ASR)
{ 
	unsigned char z;
	unsigned long int y=(unsigned long int)(f*2.1*(1024.0/1024));
	ASR[0]=Amp[0];
	z=(unsigned char)(y>>8);
	Amp[1]=(Amp[1]&0xfc);
	ASR[1]=(Amp[1]|z);
	z=(unsigned char)(y<<0);		
	ASR[2]=z;
}

/* 
* @function:    LingZhi_AD9959_SetWave
* @parameter:   [in] mood				The AD9959 work mood.
* @parameter:   [in] data				The main data of the wave.
*/
void LingZhi_AD9959_SetWave(AD9959_MoodDef mood, AD9959_DataDef* data)
{
	unsigned char channel[1]={data->chan};
	LingZhi_AD9959_WrReg(AD9959_CSR,1,channel,0);
	unsigned char FreWord[4];
	unsigned char RegData[3]={0xD0,0x00,0x00};
	unsigned char ChaRegData[3]={0x00,0x23,0x35};
	LingZhi_AD9959_WrReg(AD9959_FR1,3,RegData,0);
	LingZhi_AD9959_WrReg(AD9959_CFR,3,ChaRegData,0);
	if(mood==AD9959_MoodPha)
	{
		unsigned char PhaWord[2];
		LingZhi_AD9959_WrPhase(data->phase,PhaWord);
		LingZhi_AD9959_WrReg(AD9959_CPOW0,2,PhaWord,0);
	}
	if(mood==AD9959_MoodAmp)
	{
		unsigned char ASRWord[3];
		unsigned char AmpData[3]={0xff,0x17,0xff};   
		LingZhi_AD9959_WrAmp(data->amp,AmpData,ASRWord);
		LingZhi_AD9959_WrReg(AD9959_ACR,3,ASRWord,0);  
	}
	LingZhi_AD9959_WrFreq(data->freq,FreWord);
	LingZhi_AD9959_WrReg(AD9959_CFTW0,4,FreWord,1);
}


